package com.budwk.app.miniapp.services.impl;

import cn.dev33.satoken.annotation.SaCheckLogin;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.exception.ServiceException;
import com.budwk.app.miniapp.common.enums.RallyMateEnum;
import com.budwk.app.miniapp.common.enums.SqfwRallyEnum;
import com.budwk.app.miniapp.models.*;
import com.budwk.app.miniapp.services.CenSusPaperService;
import com.budwk.app.miniapp.services.SqfwRallyService;
import com.budwk.app.miniapp.services.SqfwRallySignService;
import com.budwk.starter.common.constant.RedisConstant;
import com.budwk.starter.common.exception.BaseException;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.database.service.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang.time.DateUtils;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@IocBean(args = {"refer:dao"})
@Slf4j
public class SqfwRallyServiceImpl extends BaseServiceImpl<SqfwRally> implements SqfwRallyService {
    public SqfwRallyServiceImpl(Dao dao) {
        super(dao);
    }

    @Inject
    private SqfwRallyService sqfwRallyService;
    @Inject
    private CenSusPaperService cenSusPaperService;

    @Inject
    private SqfwRallySignService sqfwRallySignService;

    @Inject
    private RedissonClient redissonClient;

    @Override
    public SqfwRally createOne(SqfwRally sqfwRally) {
        return sqfwRallyService.insert(sqfwRally);
    }

    @Override
    public SqfwRally getOne(String id) {
        SqfwRally sqfwRally=sqfwRallyService.fetch(id);
        if(ObjectUtil.isEmpty(sqfwRally)){
            throw new ServiceException("无法查找到对象");
        }
        return sqfwRally;
    }

    @Override
    public SqfwRally getOneInfo(String id) {
        SqfwRally sqfwRally=sqfwRallyService.fetch(id);
        if(ObjectUtil.isEmpty(sqfwRally)){
            throw new ServiceException("无法查找到对象");
        }
        if(sqfwRally.getRallyType()== SqfwRallyEnum.TONGZHI.getCode()||
                sqfwRally.getRallyType()== SqfwRallyEnum.JSONBN.getCode()){
            return sqfwRally;
        }
        sqfwRally.setSignTimeoutFlag(DateUtil.compare(new Date(), DateUtils.addDays(sqfwRally.getRallyEndTime(),1)));
        return sqfwRally;
    }

    @Override
    public boolean delOne(String id) {
        if(sqfwRallyService.delete(id)>0){
            return true;
        };
       return false;
    }

    @Override
    public SqfwRally updateOne(SqfwRally sqfwRally) {
        sqfwRallyService.updateIgnoreNull(sqfwRally);
        return sqfwRally;
    }

    @Override
    public void finishService(String id) {
        SqfwRally sqfwRally=sqfwRallyService.fetch(id);
        sqfwRally.setFinishStatus("complete");
        sqfwRallyService.update(sqfwRally);
    }

    @Override
    @SaCheckLogin
    @Aop(TransAop.READ_COMMITTED)
    public List<SqfwCenSusPaper> singUp(SqfwRallySign rallySign) {
        SqfwRally sqfwRally=  sqfwRallyService.fetch(rallySign.getRallyId());
            if(ObjectUtil.isEmpty(sqfwRally)){
                throw new BaseException("无法找到关联对象");
            }
            if(StrUtil.isEmpty(rallySign.getName())){
                throw new BaseException("请填写报名人员！");
            }

            SaSession sa=   StpUtil.getSession();
            String phone  = (String) sa.getDataMap().get("phone");
            if(StrUtil.isEmpty(phone)){
                throw new BaseException("当前登录用户手机为空");
            }
            if(sqfwRally.getFullRange()!=2) {
                    List<SqfwCenSusPaper> sqfwCenSusPaperList = cenSusPaperService.query(Cnd.where("name", "=", rallySign.getName())
                            .andNot(SqfwCenSusPaper::getCardId, "is", null));
                    if (CollectionUtil.isEmpty(sqfwCenSusPaperList)) {
                        throw new BaseException("您的信息缺失无法报名，请您联系居委会补齐信息！");
                    }

                if(StrUtil.isNotEmpty(rallySign.getBirthdayString())){
                    Optional<SqfwCenSusPaper> result = sqfwCenSusPaperList.stream().filter(s -> rallySign.getBirthdayString().equals(IdcardUtil.getBirthByIdCard(s.getCardId()))).findAny();

                    if(result.isEmpty()){
                        throw new BaseException("您的出生日期信息缺失无法报名，请您联系居委会补齐信息！");
                    }

                    if( mate( sqfwRally,result.get())){
                        throw new BaseException("抱歉，您与此次报名条件不符！");
                    }
                    BeanUtil.copyProperties(result.get(),rallySign);
                }else {
                    if(sqfwCenSusPaperList.size()>1){
                        return sqfwCenSusPaperList;
                    }
                    if( mate( sqfwRally,sqfwCenSusPaperList.get(0))){
                        throw new BaseException("抱歉，您与此次报名条件不符！");
                    }
                    BeanUtil.copyProperties(sqfwCenSusPaperList.get(0),rallySign);
                }
            }else {
                rallySign.setCity(sqfwRally.getCity());
                rallySign.setCounty(sqfwRally.getCounty());
                rallySign.setDistrict(sqfwRally.getDistrict());
                rallySign.setProvince(sqfwRally.getProvince());
                rallySign.setCommunity(sqfwRally.getCommunity());
            }
            rallySign.setCreateDate(new Date());
            rallySign.setPhone(phone);
            RLock rLock = redissonClient.getLock("singUp:" + sqfwRally.getId());
            try {
                boolean lockFlag = rLock.tryLock(3, TimeUnit.SECONDS);
                if (lockFlag) {
                    List<SqfwRallySign> dbSqfwRallySigns = sqfwRallySignService.query(Cnd.where(SqfwRallySign::getRallyId, "=", sqfwRally.getId()));
                    List<String> j = new ArrayList();
                    if (CollectionUtil.isNotEmpty(dbSqfwRallySigns)) {
                        j = dbSqfwRallySigns.stream().map(s -> s.getCardId()).collect(Collectors.toList());
                    }
                    if (sqfwRally.getFullRange() != 2 && j.contains(rallySign.getCardId())) {
                        throw new BaseException("用户已经报过名！");
                    }
                    if (StrUtil.isNotEmpty(sqfwRally.getPeoLimit())) {
                        if (j.size() == Integer.parseInt(sqfwRally.getPeoLimit())) {
                            throw new BaseException("活动报名人数已满，无法再接受新的报名。");
                        }
                    }
                    sqfwRallySignService.insert(rallySign);
                }
            }catch (InterruptedException e){
                log.error(e.getMessage());
            }finally {
                rLock.unlock();
            }
            return null;
    }
    private boolean mate(SqfwRally sqfwRally,SqfwCenSusPaper sqfwCenSusPaper){
        if(ObjectUtil.isEmpty(sqfwCenSusPaper)){
            throw new BaseException("您的信息缺失无法报名，请您联系居委会补齐信息！");
        }
        List<String> agelist=new ArrayList();
        List<String> sexlist=new ArrayList();
        List<String> arealist=new ArrayList();
        List<String> speciallist=new ArrayList();
        if(StrUtil.isNotEmpty(sqfwRally.getRallyIncludeAge())){
            if(StrUtil.isEmpty(sqfwCenSusPaper.getCardId())||!Validator.isCitizenId(sqfwCenSusPaper.getCardId())){
                throw new BaseException("您的身份证缺失无法报名，请您联系居委会补齐信息！");
            }
            agelist=JSONUtil.parseArray(sqfwRally.getRallyIncludeAge()).toList(String.class);
        }
        if(StrUtil.isNotEmpty(sqfwRally.getRallyIncludeSex())){
            if(StrUtil.isEmpty(sqfwCenSusPaper.getCardId())||!Validator.isCitizenId(sqfwCenSusPaper.getCardId())){
                throw new BaseException("您的身份证缺失无法报名，请您联系居委会补齐信息！");
            }
            int genderInt=  IdcardUtil.getGenderByIdCard(sqfwCenSusPaper.getCardId());
            if (genderInt==1){
                sqfwCenSusPaper.setGender("男");
            }else {
                sqfwCenSusPaper.setGender("女");
            }
            sexlist=JSONUtil.parseArray(sqfwRally.getRallyIncludeSex()).toList(String.class);
        }
        if(StrUtil.isNotEmpty(sqfwRally.getRallyIncludeRange())){
            speciallist=JSONUtil.parseArray(sqfwRally.getRallyIncludeRange()).toList(String.class);
        }
        if(StrUtil.isNotEmpty(sqfwRally.getRallyIncludeArea())){
            arealist=Arrays.asList(sqfwRally.getRallyIncludeArea().split("-"));
        }
        //年龄判断
        if(CollUtil.isNotEmpty(agelist)){
            if(!Validator.isCitizenId(sqfwCenSusPaper.getCardId())){
                return true;
            }
            int age= IdcardUtil.getAgeByIdCard(sqfwCenSusPaper.getCardId());
            sqfwCenSusPaper.setBirthday(IdcardUtil.getBirthDate(sqfwCenSusPaper.getCardId()));
            if(!(age> RallyMateEnum.getA(agelist.get(0))&&age<RallyMateEnum.getB(agelist.get(agelist.size()-1)))){
                return true;
            };
        }
        //性别
        if(CollUtil.isNotEmpty(sexlist)){
            if(!sexlist.contains(sqfwCenSusPaper.getGender())){
                return true;
            }
        }
        //特殊人群
        if(CollUtil.isNotEmpty(speciallist)&&!speciallist.contains("正常")){
            if(sqfwCenSusPaper.getSpecialMark().contains("、")){
                List<String> tag=Arrays.asList(sqfwCenSusPaper.getSpecialMark().split("、"));
                if(!speciallist.stream().anyMatch(tag::contains)){
                    return true;
                }
            }else {
                if(!speciallist.contains(sqfwCenSusPaper.getSpecialMark())){
                    return true;
                }
            }

        }
        if(CollUtil.isNotEmpty(arealist)){
            if(!(arealist.get(0).equals(sqfwCenSusPaper.getProvince())||
                    "直属".equals(sqfwCenSusPaper.getProvince())||
                    "直属".equals(arealist.get(0)))){
                return true;
            }
            if(!(arealist.get(1).equals(sqfwCenSusPaper.getCity())||
                    "直属".equals(sqfwCenSusPaper.getCity())||
                    "直属".equals(arealist.get(1)))){
                return true;
            }
            if(!(arealist.get(2).equals(sqfwCenSusPaper.getDistrict())||
                    "直属".equals(sqfwCenSusPaper.getDistrict())||
                    "直属".equals(arealist.get(2)))){
                return true;
            }
            if(!(arealist.get(3).equals(sqfwCenSusPaper.getCounty())||
                    "直属".equals(sqfwCenSusPaper.getCounty())||
                    "直属".equals(arealist.get(3)))){
                return true;
            }
            if(!(arealist.get(4).equals(sqfwCenSusPaper.getCommunity())||
                    "直属".equals(sqfwCenSusPaper.getCommunity())||
                    "直属".equals(arealist.get(4)))){
                return true;
            }

        }

        return false;
    }




}


